package com.vik.webgallery.web;

import java.io.File;
import java.io.IOException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.activation.MimetypesFileTypeMap;
import javax.annotation.Resource;
import javax.security.auth.login.AppConfigurationEntry;
import javax.servlet.http.HttpServletRequest;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;

import com.vik.webgallery.beans.Comment;
import com.vik.webgallery.beans.Gallery;
import com.vik.webgallery.beans.Image;
import com.vik.webgallery.beans.Photo;
import com.vik.webgallery.beans.User;
import com.vik.webgallery.persistence.CommentMapper;
import com.vik.webgallery.persistence.GalleryMapper;
import com.vik.webgallery.persistence.PhotoMapper;
import com.vik.webgallery.persistence.UserMapper;

@Controller
public class GalleryController {
	
	private static final Logger logger = LoggerFactory.getLogger(GalleryController.class);
	
	@Resource(name = "appConfig")
	private Properties appProperties;

	@Autowired
	public GalleryMapper galleryMapper;
	
	@Autowired
	public UserMapper userMapper;
	
	@Autowired
	public PhotoMapper photoMapper;
	
	@Autowired
	public CommentMapper commentMapper;
	
	@RequestMapping(value="/gallery")
	public String showGalleries(Model model){
		
		ArrayList<Gallery> galleries = galleryMapper.getGalleries();
		
		for (Gallery g:galleries){
			g.setOwner(userMapper.getUserById(g.getOwnerId()));
		}
		
		model.addAttribute("galleries", galleries);
		
		return "/gallery/list";
	}
	
	@RequestMapping(value="/gallery/add")
	public String addGallery(Model model){
		
		Gallery gallery = new Gallery();
		model.addAttribute("gallery", gallery);
		
		return "/gallery/add1";
	}
	
	@RequestMapping(value="/gallery/add", method=RequestMethod.POST)
	public String addGallery(@ModelAttribute Gallery gallery, Model model, BindingResult result, HttpServletRequest request, Principal principal){
		
		if (StringUtils.trimAllWhitespace(gallery.getName()).isEmpty()){
			result.rejectValue("name", "empty", "Nazev galerie nesmi byt prazdny");
			return "/gallery/add1";
		}else{
			
			// Kontrola nazvu galerie
			if (galleryMapper.getIdenticalGalleriesCount(gallery) > 0){
				result.rejectValue("name", "duplicate", "Galerie s timto nazvem jiz existuje");
				return "/gallery/add1";
			}
			
			gallery.setOwner(userMapper.getUser(principal.getName()));
			gallery.setRootFolder(gallery.getName());
			request.getSession().setAttribute("gallery", gallery);
			
			galleryMapper.addGallery(gallery);
			
			
			
			return "redirect:/gallery/add/" + gallery.getId();
		}
		
	}
	
	
	@RequestMapping(value="gallery/add/{galleryId}", method=RequestMethod.GET)
	public String addPhoto(@PathVariable long galleryId, Model model){

		Photo photo = new Photo();
		model.addAttribute("photo", photo);
		model.addAttribute("fileInfo", "Nothing uploaded yet");
		
		
		// Nacteni nahranych fotografii
		Gallery g = galleryMapper.getGallery(galleryId);
		g.setOwner(userMapper.getUserById(g.getOwnerId()));
		
		List<Photo> photos = photoMapper.getPhotosByGalleryId(g.getId());
		for (Photo p:photos){
			p.setGallery(g);
		}
		
		model.addAttribute("photos", photos);
		model.addAttribute("gallery", g);
		
		return "gallery/add2";
	}
	
	
	@RequestMapping(value="gallery/add/{galleryId}", method=RequestMethod.POST)
	public String savePhoto(@ModelAttribute Photo photo, @PathVariable long galleryId, Model model, BindingResult result, HttpServletRequest request, Principal principal){
			
		MultipartFile file = photo.getFile();

		// Kontrola, zda je to obrazek
		Image i;
		
		try {
			i = new Image(file);
		} catch (IOException e1) {
			model.addAttribute("fileInfo", "Nepodarilo se nacist soubor");
			return "/gallery/add2";
		}
		
		if (!i.isImage()){
			model.addAttribute("fileInfo", "Naimportovany soubor neni obrazek");
			return "/gallery/add2";
		}
		
		
		Gallery g = (Gallery)galleryMapper.getGallery(galleryId);
		
		// Upload obrazku a ulozeni do databaze
		if (file.isEmpty()){
			model.addAttribute("fileInfo", "Nepodarilo se uploadovat soubor");
		}else{
			
			model.addAttribute("fileInfo", "Soubor uploadovan. Velikost: " + file.getSize()/1000 + "kB");
			
			photo.setGallery(g);
			
			String galleryFolder = g.getRootFolder();
			String userFolder = principal.getName();
			
			// Kontrola duplicity
			if (photoMapper.countPhotosWithSameName(photo) > 0){
				model.addAttribute("fileInfo", "Soubor s timto nazvem je jiz v galerii ulozen ");
				return "/gallery/add2";
			}
			
			
			// Vytvoreni slozky
			String photoDir = appProperties.get("UPLOAD_DIR") + File.separator + userFolder + File.separator + galleryFolder;
			String thumbDir = photoDir + File.separator + "thumbnails" + File.separator;
			
			File dir = new File(thumbDir);
			
			if (!dir.exists() || !dir.isDirectory()){
				dir.mkdirs();
			}
	
			
			try {
				
				// Save image
				i.resizeImage(800, 600);
				i.saveImage(photoDir + File.separator + file.getOriginalFilename());
				// Save thumbnail
				i.resizeImage(120, 90);
				i.saveImage(thumbDir + File.separator + file.getOriginalFilename());
				
				photo.setFileName(file.getOriginalFilename());
				photoMapper.insert(photo);
				
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		// Nacteni nahranych fotografii
		
		List<Photo> photos = photoMapper.getPhotosByGalleryId(g.getId());
		for (Photo p:photos){
			Gallery glr = galleryMapper.getGallery(p.getGalleryId());
			glr.setOwner(userMapper.getUserById(glr.getOwnerId()));
			p.setGallery(glr);
		}
		
		model.addAttribute("photos", photos);
		model.addAttribute("gallery", g);
		
		
		return "/gallery/add2";
	}
	
	
	@RequestMapping(value="gallery/show/{galleryName}", method=RequestMethod.GET)
	public String showPhotosFromGallery(@PathVariable long galleryName, Model model){
		// TODO do url odkazu vlo�it n�jak� n�zev galerie m�sto id (mo�n� rootFolder?)
		
		
		// Nacteni galerie
		Gallery gallery = galleryMapper.getGallery(galleryName);
		gallery.setOwner(userMapper.getUserById(gallery.getOwnerId()));
		
		// Nacteni fotografii
		ArrayList<Photo> photos = photoMapper.getPhotosByGalleryId(galleryName);
		
		// Nacteni komentaru
		for (Photo p:photos){
			p.setComments(commentMapper.getCommentsByPhotoId(p.getId()));
		}
		
		model.addAttribute("gallery", gallery);
		model.addAttribute("photos", photos);
		
		return "/gallery/showPhotos";
	}
	
	@RequestMapping(value="gallery/finish/{galleryId}", method=RequestMethod.GET)
	public String finishGallery(@PathVariable long galleryId, Model model){
		
		ArrayList<Photo> photos = photoMapper.getPhotosByGalleryId(galleryId);
		Gallery g = galleryMapper.getGallery(galleryId);
		g.setOwner(userMapper.getUserById(g.getOwnerId()));
		
		for (Photo p:photos){
			Gallery gal = galleryMapper.getGallery(p.getGalleryId());
			gal.setOwner(userMapper.getUserById(gal.getOwnerId()));
			p.setGallery(gal);
		}
		
		model.addAttribute("photos", photos);
		model.addAttribute("gallery", g);
		
		return "gallery/add3";
	}
	
	@RequestMapping(value="/gallery/add/{galleryId}/deletephoto/{photoId}", method=RequestMethod.GET)
	public String deletePhoto(@PathVariable long galleryId, @PathVariable long photoId, Model model, Principal principal){
		
		// Nacteni objektu
		Photo p = photoMapper.getPhotoById(photoId);
		Gallery g = galleryMapper.getGallery(p.getGalleryId());
		g.setOwner(userMapper.getUserById(g.getOwnerId()));
		p.setGallery(g);
		
		// Kontrola opravneni
		User loggedUser = userMapper.getUser(principal.getName());
	
		if (p.getGallery().getOwnerId() != loggedUser.getId()){
			return "redirect:/gallery/add/" + galleryId;
		}
		// Odstraneni komentare
		commentMapper.deleteCommentsByPhotoId(photoId);
		
		// Odstraneni fotku z db
		photoMapper.delete(p);
		
		// Odstraneni soubory
		p.deleteFiles((String)appProperties.get("UPLOAD_DIR"));
		
		return "redirect:/gallery/add/" + galleryId;
	}
	
	@RequestMapping(value="gallery/show/{galleryName}/{photoId}", method=RequestMethod.GET)
	public String showPhoto(@PathVariable long galleryName, @PathVariable long photoId, Model model){
		
		// Nacteni fotografie
		Photo photo = photoMapper.getPhotoById(photoId);
		Gallery gallery = galleryMapper.getGallery(galleryName);
		gallery.setOwner(userMapper.getUserById(gallery.getOwnerId()));
		photo.setGallery(gallery);
		
		// Nacteni komentaru (+ doplneni useru)
		ArrayList<Comment> comments = commentMapper.getCommentsByPhotoId(photo.getId());
		for (Comment c: comments){
			c.setAuthor(userMapper.getUserById(c.getAuthorId()));
		}
		
		photo.setComments(comments);
		
		// Vytvoreni instance komentare pro formular
		Comment comment = new Comment();
				
		model.addAttribute("comment", comment);
		model.addAttribute("photo", photo);
		
		return "/gallery/showPhoto";
	}
	
	@RequestMapping(value="gallery/show/{galleryName}/{photoId}", method=RequestMethod.POST)
	public String savePhotoComment(@PathVariable long galleryName, @PathVariable long photoId, @ModelAttribute Comment comment, Model model, BindingResult result, Principal principal){
		
		
		if (StringUtils.trimAllWhitespace(comment.getText()).isEmpty()){
			result.rejectValue("text", "empty", "Text koment��e nesm� b�t pr�zdn�");
			return "/gallery/" + galleryName + "/" + photoId;
		}else{
			
			comment.setPhotoId(photoId);
			comment.setAuthor(userMapper.getUser(principal.getName()));
			
			commentMapper.insertComment(comment);
			
			return "redirect:/gallery/show/" + galleryName + "/" + photoId;
		}
		

	}
}

